package com.ruoyi.web.controller.system;

import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.OrderConstants;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.entity.BO.StatisticsBO;
import com.ruoyi.common.entity.DO.member.MemberBalanceRecordDO;
import com.ruoyi.common.entity.VO.order.MemberRechargeOrderVO;
import com.ruoyi.common.entity.VO.order.ShopOrderSearchVO;
import com.ruoyi.common.entity.VO.order.ShopPetrolOrderVO;
import com.ruoyi.common.entity.VO.shop.ShopSearchVO;
import com.ruoyi.common.entity.VO.shop.ShopVO;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.*;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.web.controller.member.mapper.IBackMemberBalanceRecordMapper;
import com.ruoyi.web.controller.member.mapper.IBackMemberMapper;
import com.ruoyi.web.controller.order.mapper.IBackMemberRechargeOrderMapper;
import com.ruoyi.web.controller.order.mapper.IBackShopPetrolOrderMapper;
import com.ruoyi.web.controller.shop.service.IBackShopService;
import me.chanjar.weixin.common.util.DataUtils;
import org.jsoup.helper.DataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.util.*;

/**
 * 首页 业务处理
 *
 * @author ruoyi
 */
@Controller
public class SysIndexController extends BaseController {
    @Autowired
    private ISysMenuService menuService;

    @Resource
    private IBackShopService shopService;

    @Resource
    private ISysConfigService configService;

    @Resource
    private IBackMemberMapper backMemberMapper;

    @Resource
    private SysPasswordService passwordService;

    @Resource
    private IBackShopPetrolOrderMapper shopPetrolOrderMapper;

    @Resource
    private IBackMemberRechargeOrderMapper backMemberRechargeOrderMapper;

    @Resource
    private IBackMemberBalanceRecordMapper backMemberBalanceRecordMapper;

    // 系统首页
    @GetMapping("/index")
    public String index(ModelMap mmap) {
        // 取身份信息
        SysUser user = getSysUser();
        // 根据用户id取出菜单
        List<SysMenu> menus = menuService.selectMenusByUser(user);
        mmap.put("menus", menus);
        mmap.put("user", user);
        mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
        mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
        Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer"), true);
        Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView"), true);
        mmap.put("footer", footer);
        mmap.put("tagsView", tagsView);
        mmap.put("mainClass", contentMainClass(footer, tagsView));
        mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear());
        mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled());
        mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
        mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
        mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")));
        //dev-append 当前的店铺ID和可切换的店铺列表 10lines
        mmap.put("shopId", ShiroUtils.getShopId());
        ShopSearchVO shopSearchVO = new ShopSearchVO();
        shopSearchVO.setIsDelete(0);
        shopSearchVO.setReviewStatus(1);
        List<ShopVO> shopList = shopService.searchList(shopSearchVO);
        ShopVO shopVO = new ShopVO();
        shopVO.setId(0L);
        shopVO.setShopName("切换站点");
        shopList.add(shopVO);
        mmap.put("shopList", shopList);

        // 菜单导航显示风格
        String menuStyle = configService.selectConfigByKey("sys.index.menuStyle");
        // 移动端，默认使左侧导航菜单，否则取默认配置
        String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;

        // 优先Cookie配置导航菜单
        Cookie[] cookies = ServletUtils.getRequest().getCookies();
        for (Cookie cookie : cookies) {
            if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName())) {
                indexStyle = cookie.getValue();
                break;
            }
        }
        String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
        return webIndex;
    }

    // 锁定屏幕
    @GetMapping("/lockscreen")
    public String lockscreen(ModelMap mmap) {
        mmap.put("user", getSysUser());
        ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
        return "lock";
    }

    // 解锁屏幕
    @PostMapping("/unlockscreen")
    @ResponseBody
    public AjaxResult unlockscreen(String password) {
        SysUser user = getSysUser();
        if (StringUtils.isNull(user)) {
            return AjaxResult.error("服务器超时，请重新登录");
        }
        if (passwordService.matches(user, password)) {
            ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN);
            return AjaxResult.success();
        }
        return AjaxResult.error("密码不正确，请重新输入。");
    }

    // 切换主题
    @GetMapping("/system/switchSkin")
    public String switchSkin() {
        return "skin";
    }

    // 切换菜单
    @GetMapping("/system/menuStyle/{style}")
    public void menuStyle(@PathVariable String style, HttpServletResponse response) {
        CookieUtils.setCookie(response, "nav-style", style);
    }

    // 系统介绍
    @GetMapping("/system/main")
    public String main(ModelMap mmap) {
        if (0 == ShiroUtils.getShopId()) {
            return "redirect:/back/shop/switchShop";
        }
        mmap.put("version", RuoYiConfig.getVersion());
        // 数据统计
        Map<String, BigDecimal> map = getShopStatistics(ShiroUtils.getShopId(), 1L, DateUtils.getDate() + " 00:00:00", DateUtils.getDate() + " 23:59:59");
        mmap.put("wxPayTotal92", map.get("wxPayTotal"));
        mmap.put("balancePayTotal92", map.get("balancePayTotal"));
        mmap.put("offlinePayTotal92", map.get("offlinePayTotal"));
        mmap.put("orderCostTotal92", map.get("orderCostTotal"));
        mmap.put("payCostTotal92", map.get("payCostTotal"));
        mmap.put("quantityTotal92", map.get("quantityTotal"));
        map = getShopStatistics(ShiroUtils.getShopId(), 2L, DateUtils.getDate() + " 00:00:00", DateUtils.getDate() + " 23:59:59");
        mmap.put("wxPayTotal95", map.get("wxPayTotal"));
        mmap.put("balancePayTotal95", map.get("balancePayTotal"));
        mmap.put("offlinePayTotal95", map.get("offlinePayTotal"));
        mmap.put("orderCostTotal95", map.get("orderCostTotal"));
        mmap.put("payCostTotal95", map.get("payCostTotal"));
        mmap.put("quantityTotal95", map.get("quantityTotal"));
        map = getShopStatistics(ShiroUtils.getShopId(), 3L, DateUtils.getDate() + " 00:00:00", DateUtils.getDate() + " 23:59:59");
        mmap.put("wxPayTotal0", map.get("wxPayTotal"));
        mmap.put("balancePayTotal0", map.get("balancePayTotal"));
        mmap.put("offlinePayTotal0", map.get("offlinePayTotal"));
        mmap.put("orderCostTotal0", map.get("orderCostTotal"));
        mmap.put("payCostTotal0", map.get("payCostTotal"));
        mmap.put("quantityTotal0", map.get("quantityTotal"));
        map = getShopStatistics(ShiroUtils.getShopId(), 13L, DateUtils.getDate() + " 00:00:00", DateUtils.getDate() + " 23:59:59");
        mmap.put("wxPayTotal10", map.get("wxPayTotal"));
        mmap.put("balancePayTotal10", map.get("balancePayTotal"));
        mmap.put("offlinePayTotal10", map.get("offlinePayTotal"));
        mmap.put("orderCostTotal10", map.get("orderCostTotal"));
        mmap.put("payCostTotal10", map.get("payCostTotal"));
        mmap.put("quantityTotal10", map.get("quantityTotal"));
        map = getRechargeStatistics(ShiroUtils.getShopId(), DateUtils.getDate() + " 00:00:00", DateUtils.getDate() + " 23:59:59");
        mmap.put("rechargePayTotal", map.get("rechargePayTotal"));
        //获取前前一天8点半和前一天八点半的时间
        String startTime="";
        String endTime="";
        Calendar calendar = Calendar.getInstance();
        if(DateUtils.getNowDate().getTime()> DateUtils.parseDate(DateUtils.getDate()+" 08:30:00").getTime()){
            //当前时间大于当天早上8点半
            //浏览前一天08：30到今天08：30的时间
            calendar.add(GregorianCalendar.DATE, -1);
            long tmpTime = calendar.getTimeInMillis();
            startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date(tmpTime))+" 08:30:00";
            endTime = DateUtils.getDate() + " 08:30:00";
        }else{
            //当前时间小于当天早上8点半
            //浏览前前一天08：30到前天08：30的时间
            calendar.add(GregorianCalendar.DATE, -1);
            long tmpTime = calendar.getTimeInMillis();
            endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date(tmpTime))+" 08:30:00";
            calendar.add(GregorianCalendar.DATE, -1);
            tmpTime = calendar.getTimeInMillis();
            startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date(tmpTime))+" 08:30:00";
        }
        map = getExchangeStatistics(ShiroUtils.getShopId(), startTime, endTime);
        mmap.put("rechargePayTotalB", map.get("rechargePayTotal"));
        mmap.put("balancePetrolTotalB", map.get("balancePetrolTotal"));
        mmap.put("discountTotalB", map.get("discountTotal"));
        mmap.put("balanceTotalB", map.get("balanceTotal"));
        mmap.put("balancePetrolNoDiscountB", map.get("balancePetrolNoDiscount"));
        mmap.put("wxPayPetrolTotalB1", map.get("wxPayPetrolTotal1"));
        mmap.put("wxPayPetrolTotalB2", map.get("wxPayPetrolTotal2"));
        mmap.put("wxPayPetrolTotalB", map.get("wxPayPetrolTotal"));

        mmap.put("nowTime", DateUtils.getTime());
        mmap.put("allRechargeTotal", backMemberRechargeOrderMapper.sumTotalAmount(ShiroUtils.getShopId()));
        mmap.put("allRechargeGiftAmountTotal", backMemberRechargeOrderMapper.sumGiftAmount(ShiroUtils.getShopId()));
        BigDecimal allAdd = backMemberBalanceRecordMapper.sumBackRechargeAmount(ShiroUtils.getShopId());
        BigDecimal addDesc = backMemberBalanceRecordMapper.sumBackDescAmount(ShiroUtils.getShopId());
        if(null != addDesc){
            allAdd = allAdd.add(addDesc);
        }
        mmap.put("allBackRechargeBalanceTotal", allAdd);
        mmap.put("allBalanceTotal", backMemberMapper.sumTotalBalance(ShiroUtils.getShopId()));
        mmap.put("allBalancePayTotal", shopPetrolOrderMapper.sumBalancePayTotal(ShiroUtils.getShopId()));
        mmap.put("exchangeStartTime", startTime);
        mmap.put("exchangeEndTime", endTime);

        return "main";
    }

    @PostMapping("/getStatistics")
    @ResponseBody
    public AjaxResult getStatistics(Long productId, String startTime, String endTime) {
        if (0 == ShiroUtils.getShopId()) {
            throw new BusinessException("请先切换站点！");
        }
        Map<String, BigDecimal> mmap = new HashMap<>();
        if (productId < 9900) {
            mmap = getShopStatistics(ShiroUtils.getShopId(), productId, startTime, endTime);
            return success(mmap);
        } else {
            if (productId == 9901L) {
                mmap = getRechargeStatistics(ShiroUtils.getShopId(), startTime, endTime);
            } else if (productId == 9902L) {
                mmap = getExchangeStatistics(ShiroUtils.getShopId(), startTime, endTime);
            }
            return success(mmap);
        }
    }

    //dev-append
    private Map<String, BigDecimal> getShopStatistics(Long shopId, Long productId, String startTime, String endTime) {
        Map<String, BigDecimal> map = new HashMap<>();
        ShopOrderSearchVO searchVO = new ShopOrderSearchVO();
        searchVO.setShopId(shopId);
        searchVO.setOrderStatus(OrderConstants.OrderStatusEnum.COMPLETE.getValue());
        searchVO.setPayTimeBegin(startTime);
        searchVO.setProductId(productId);
        searchVO.setPayTimeEnd(endTime);
        List<ShopPetrolOrderVO> orderList = shopPetrolOrderMapper.searchList(searchVO);
        BigDecimal wxPayTotal = BigDecimal.ZERO;
        BigDecimal balancePayTotal = BigDecimal.ZERO;
        BigDecimal offlinePayTotal = BigDecimal.ZERO;
        BigDecimal orderCostTotal = BigDecimal.ZERO;
        BigDecimal payCostTotal = BigDecimal.ZERO;
        BigDecimal quantityTotal = BigDecimal.ZERO;
        if (orderList.size() > 0) {
            for (ShopPetrolOrderVO one : orderList) {
                if (OrderConstants.OrderPayWayEnum.BALANCE_PAY.getValue() == one.getPayWay()) {
                    balancePayTotal = balancePayTotal.add(one.getPayCost());
                } else if (OrderConstants.OrderPayWayEnum.WX_PAY.getValue() == one.getPayWay()) {
                    wxPayTotal = wxPayTotal.add(one.getPayCost());
                } else {
                    offlinePayTotal = offlinePayTotal.add(one.getPayCost());
                }
                orderCostTotal = orderCostTotal.add(one.getOrderCost());
                payCostTotal = payCostTotal.add(one.getPayCost());
                quantityTotal = quantityTotal.add(one.getProductQuantity());
            }
        }
        map.put("wxPayTotal", wxPayTotal);
        map.put("balancePayTotal", balancePayTotal);
        map.put("offlinePayTotal", offlinePayTotal);
        map.put("orderCostTotal", orderCostTotal);
        map.put("payCostTotal", payCostTotal);
        map.put("quantityTotal", quantityTotal);
        return map;
    }

    //dev-append
    private Map<String, BigDecimal> getRechargeStatistics(Long shopId, String startTime, String endTime) {
        Map<String, BigDecimal> map = new HashMap<>();
        ShopOrderSearchVO searchVO = new ShopOrderSearchVO();
        searchVO.setShopId(shopId);
        searchVO.setOrderStatus(OrderConstants.OrderStatusEnum.COMPLETE.getValue());
        searchVO.setPayTimeBegin(startTime);
        searchVO.setPayTimeEnd(endTime);
        List<MemberRechargeOrderVO> orderList = backMemberRechargeOrderMapper.searchList(searchVO);
        BigDecimal payCostTotal = BigDecimal.ZERO;
        if (orderList.size() > 0) {
            for (MemberRechargeOrderVO one : orderList) {
                payCostTotal = payCostTotal.add(one.getPayAmount());
            }
        }
        map.put("rechargePayTotal", payCostTotal);
        return map;
    }

    //dev-append
    private Map<String, BigDecimal> getExchangeStatistics(Long shopId, String startTime, String endTime) {
        Map<String, BigDecimal> map = new HashMap<>();
        BigDecimal rechargePayTotal = BigDecimal.ZERO;
        BigDecimal wxPayPetrolTotal = BigDecimal.ZERO;
        BigDecimal wxPayPetrolTotal1 = BigDecimal.ZERO;//汽油微信支付
        BigDecimal wxPayPetrolTotal2 = BigDecimal.ZERO;//柴油微信支付
        BigDecimal balancePayTotal = BigDecimal.ZERO;
        BigDecimal offlinePayTotal = BigDecimal.ZERO;
        BigDecimal discountTotal = BigDecimal.ZERO;
        //剩余余额合计
        BigDecimal balanceTotal = BigDecimal.ZERO;
        BigDecimal balancePetrolNoDiscount = BigDecimal.ZERO;
        ShopOrderSearchVO searchVO = new ShopOrderSearchVO();
        searchVO.setShopId(shopId);
        searchVO.setOrderStatus(OrderConstants.OrderStatusEnum.COMPLETE.getValue());
        searchVO.setPayTimeBegin(startTime);
        searchVO.setPayTimeEnd(endTime);
        List<ShopPetrolOrderVO> orderList = shopPetrolOrderMapper.searchList(searchVO);
        if (orderList.size() > 0) {
            for (ShopPetrolOrderVO one : orderList) {
                if (OrderConstants.OrderPayWayEnum.BALANCE_PAY.getValue() == one.getPayWay()) {
                    balancePayTotal = balancePayTotal.add(one.getPayCost());
                    balancePetrolNoDiscount = balancePetrolNoDiscount.add(one.getOrderCost());
                } else if (OrderConstants.OrderPayWayEnum.WX_PAY.getValue() == one.getPayWay()) {
                    if(one.getProductName().contains("汽油")){
                        wxPayPetrolTotal1 = wxPayPetrolTotal1.add(one.getPayCost());
                    }else if(one.getProductName().contains("柴油")){
                        wxPayPetrolTotal2 = wxPayPetrolTotal2.add(one.getPayCost());
                    }
                    wxPayPetrolTotal = wxPayPetrolTotal.add(one.getPayCost());
                } else {
                    offlinePayTotal = offlinePayTotal.add(one.getPayCost());
                }
                discountTotal = discountTotal.add(one.getDiscountAmount());
            }
        }
        searchVO = new ShopOrderSearchVO();
        searchVO.setShopId(shopId);
        searchVO.setOrderStatus(OrderConstants.OrderStatusEnum.COMPLETE.getValue());
        searchVO.setPayTimeBegin(startTime);
        searchVO.setPayTimeEnd(endTime);
        List<MemberRechargeOrderVO> rechargeOrderList = backMemberRechargeOrderMapper.searchList(searchVO);
        if (orderList.size() > 0) {
            for (MemberRechargeOrderVO one : rechargeOrderList) {
                rechargePayTotal = rechargePayTotal.add(one.getPayAmount());
            }
        }
        List<MemberBalanceRecordDO> recordList = backMemberBalanceRecordMapper.searchListForStatic(shopId, endTime);
        Set<Long> memberIdSet = new LinkedHashSet<>();
        for (MemberBalanceRecordDO one : recordList
        ) {
            if (memberIdSet.add(one.getMemberId())) {
                balanceTotal = balanceTotal.add(one.getNewBalance());
            }
        }
        map.put("rechargePayTotal", rechargePayTotal);
        map.put("balancePetrolTotal", balancePayTotal);
        map.put("discountTotal", discountTotal);
        map.put("balanceTotal", balanceTotal);
        map.put("balancePetrolNoDiscount", balancePetrolNoDiscount);
        map.put("wxPayPetrolTotal1", wxPayPetrolTotal1);
        map.put("wxPayPetrolTotal2", wxPayPetrolTotal2);
        map.put("wxPayPetrolTotal", wxPayPetrolTotal);
        return map;
    }

    // content-main class
    public String contentMainClass(Boolean footer, Boolean tagsView) {
        if (!footer && !tagsView) {
            return "tagsview-footer-hide";
        } else if (!footer) {
            return "footer-hide";
        } else if (!tagsView) {
            return "tagsview-hide";
        }
        return StringUtils.EMPTY;
    }

    // 检查初始密码是否提醒修改
    public boolean initPasswordIsModify(Date pwdUpdateDate) {
        Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
        return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
    }

    // 检查密码是否过期
    public boolean passwordIsExpiration(Date pwdUpdateDate) {
        Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
        if (passwordValidateDays != null && passwordValidateDays > 0) {
            if (StringUtils.isNull(pwdUpdateDate)) {
                // 如果从未修改过初始密码，直接提醒过期
                return true;
            }
            Date nowDate = DateUtils.getNowDate();
            return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
        }
        return false;
    }
}
